#此文件未上传云
import zlib,sys
import concurrent.futures
from Crypto.Hash import SHA1, SHA224, SHA256, SHA384, SHA512, MD5

# 全局变量
BUFFER_SIZE = 64 * 1024

def calculate_hash(file_path, hash_function):
    hash_obj = hash_function.new()
    with open(file_path, "rb") as f:
        while True:
            byte_block = f.read(BUFFER_SIZE)
            if not byte_block:
                break
            hash_obj.update(byte_block)
    return hash_obj.hexdigest()

def calculate_crc32(file_path):
    crc32_value = 0
    with open(file_path, "rb") as f:
        while True:
            byte_block = f.read(BUFFER_SIZE)
            if not byte_block:
                break
            crc32_value = zlib.crc32(byte_block, crc32_value)
    return format(crc32_value & 0xFFFFFFFF, '08x')


def main() ->bool:
    # 用户输入要计算的哈希值
    print('输入q退出程序,r重启程序')

    r = False
    while True:
        file_path = input("请输入文件路径(可拖放文件到窗口上方,自动去除首尾引号): ")
        if file_path == 'q':
            sys.exit()
        elif file_path == 'r':
            r = True
            break
        try:
            if file_path[0] in ['\'', '\"', "'", "’"]:
                file_path = file_path[1:]
                break
            else:
                break
        except IndexError:
            pass
    if r:
        return False
    if file_path[-1] in ['\'', '\"', "'", "’"]:
        file_path = file_path[:-1]
    print(file_path)
    try:
        with open(file_path, "rb") as f:
            pass
    except (FileNotFoundError,OSError):
        print('请检查文件路径')
        return False

    hash_types = input("请输入要计算的哈希值（CRC32, MD5, SHA1, SHA224, SHA256, SHA384, SHA512，以英文逗号分隔,回车计算全部）: ").replace(' ','').split(',')
    if hash_types ==['q']:
        return True
    elif hash_types ==['r']:
        return False
    a = set(hash_types)
    b = set('CRC32,MD5,SHA1,SHA224,SHA256,SHA384,SHA512'.split(','))
    if hash_types == ['']:
        hash_types = 'CRC32, MD5, SHA1, SHA224, SHA256, SHA384, SHA512'.replace(' ', '').split(',')
    else:
        if a & b != a:
            print(f'暂不支持计算{a-b}')
            return False
    hash_types = [ht.strip() for ht in hash_types]

    # 使用线程池并行计算哈希
    with concurrent.futures.ThreadPoolExecutor() as executor:
        futures = {}
        if "CRC32" in hash_types:
            futures["CRC32"] = executor.submit(calculate_crc32, file_path)
        if "MD5" in hash_types:
            futures["MD5"] = executor.submit(calculate_hash, file_path, MD5)
        if "SHA1" in hash_types:
            futures["SHA1"] = executor.submit(calculate_hash, file_path, SHA1)
        if "SHA224" in hash_types:
            futures["SHA224"] = executor.submit(calculate_hash, file_path, SHA224)
        if "SHA256" in hash_types:
            futures["SHA256"] = executor.submit(calculate_hash, file_path, SHA256)
        if "SHA384" in hash_types:
            futures["SHA384"] = executor.submit(calculate_hash, file_path, SHA384)
        if "SHA512" in hash_types:
            futures["SHA512"] = executor.submit(calculate_hash, file_path, SHA512)

        # 输出结果
        for label, future in futures.items():
            hash_result = future.result()
            print(f"{label}: {hash_result}")

if __name__ == "__main__":
    while True:
        if main():
            break

